package com.xuecheng.ucenter.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.ucenter.mapper.XcUserMapper;
import com.xuecheng.ucenter.model.dto.AuthParamsDto;
import com.xuecheng.ucenter.model.dto.XcUserExt;
import com.xuecheng.ucenter.model.po.XcUser;
import com.xuecheng.ucenter.service.AuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import springfox.documentation.spring.web.json.Json;

@Service
public class UserServiceImpl implements UserDetailsService {

    @Autowired
    private AuthService authService;

    //  注入spring容器
    @Autowired
    ApplicationContext applicationContext;

    //要连接数据库进行查询
    //通过用户名查询用户信息
    //传入的s已经修改为了 统一认证参数 AuthParamsDto
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {

        AuthParamsDto authParamsDto = null;

        try {
            authParamsDto = JSON.parseObject(s, AuthParamsDto.class);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("请求参数不合法");
        }

        //我们使用统一认证方式
        //通过认证参数在spring容器中获取对应的认证方式impl
        String authType = authParamsDto.getAuthType();
        //拼接
        String beanName = authType + "_authservice";
        //获取对应的认证方法
        AuthService bean = applicationContext.getBean(beanName, AuthService.class);
        //执行认证方式
        XcUserExt xcUserExt = bean.execute(authParamsDto);
        if(xcUserExt == null){
            throw new RuntimeException("用户不存在");
        }

        //查询和封装用户信息
        return getUserPrincipal(xcUserExt);
    }

    /**
     * 根据用户信息封装用户信息
     * @param xcUserExt
     * @return
     */
    private UserDetails getUserPrincipal(XcUserExt xcUserExt) {

        //其实就是完善用户信息，将用户信息封装成UserDetails对象，返回给spring security
        //密码要单独另设
        String password = xcUserExt.getPassword();

        //设置用户权限，如果不加报Cannot pass a null GrantedAuthority collection
        String[] authorities = {"p1"};

        //将用户信息中的密码设置为空，防止密码泄露
        xcUserExt.setPassword(null);

        //将用户信息转为json字符串
        String jsonString = JSON.toJSONString(xcUserExt);
        //封装用户信息
        UserDetails userDetails = User.withUsername(jsonString).password(password).authorities(authorities).build();
        return userDetails;
    }
}
